import java.rmi.NoSuchObjectException;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

import edu.rit.ds.Lease;
import edu.rit.ds.RemoteEventGenerator;
import edu.rit.ds.RemoteEventListener;
import edu.rit.ds.registry.AlreadyBoundException;
import edu.rit.ds.registry.RegistryProxy;

/**
 * 
 */

/**
 * @author hemangthakkar
 *
 */
public class Slave implements SlaveInt {
	private String host;
	private int port;
	private int id;
	private int[][] matrixA;
	private int[][] matrixB;
	private int size;
	private RegistryProxy registry;
	private RemoteEventGenerator<SlaveEvent> eventGen;
	
	public Slave(String[] args) throws Exception{
		host = args[0];
		try{
			port = Integer.parseInt(args[1]);
		}catch(NumberFormatException e){
			throw new IllegalArgumentException("Port number not valid");
		}
		try{
			id = Integer.parseInt(args[2]);
		}catch(NumberFormatException e){
			throw new IllegalArgumentException("Id not valid");
		}
		registry = new RegistryProxy(host,port);
		UnicastRemoteObject.exportObject (this,0);
		try{
			//Bind this object to RegistryServer
			registry.bind (id+"",this);
		}	
		catch(AlreadyBoundException exc){
			try{
				registry.rebind (id+"",this);
			}
			catch (NoSuchObjectException exc2){ 		
			}
			
		}
		catch(RemoteException exc){
			try{
				UnicastRemoteObject.unexportObject (this,true);
			}
			catch(NoSuchObjectException exc2){ 		
			}
			throw exc;
		}
		eventGen = new RemoteEventGenerator<SlaveEvent>();
	}

	public void sendMatrix(int[][] a ,int[][] b,int size) throws RemoteException {
		// TODO Auto-generated method stub
		this.size =size;
		this.matrixA = new int[size][size];
		this.matrixB = new int[size][size];
		for(int i = 0;i<size;i++)
			for(int j = 0;j<size;j++){
				this.matrixA[i][j]=a[i][j];
				this.matrixB[i][j]=b[i][j];
			}
	}
	public void calculate(int col){
		new CalcThread(col).start();
	}
	public class CalcThread extends Thread{
		private int colId;

		
		public CalcThread(int col){
			colId = col;
			
		}

		public void run() {
			int[] result = new int[size];
			int i,j,temp=0;
			for(i =0;i<size;i++){
				for(j=0; j<size; j++){
					temp+=matrixA[i][j]*matrixB[j][colId];
				}
				result[i]=temp;
			}
			reporter(result,colId);
		}
		
	}
	public Lease addListener(RemoteEventListener<SlaveEvent> listener)
			throws RemoteException {
		// TODO Auto-generated method stub
		return eventGen.addListener(listener);
	}
	public void reporter(int[] result,int colId){
		eventGen.reportEvent(new SlaveEvent(colId,result));
	}
}
